java JPA onetomany casecade在子表中插入同一记录两次
我正在尝试使用casecadeALL插入一个包含一对多关系表的记录。 当任何DML发生在表上时,我有审计信息,在审计表中插入、更新或删除条目。当我运行insert时,它可以在基表中插入记录,但在审计期间,我看到子表有2个条目用于单次插入。 它正在用相同的记录更新表。 无法理解为什么casecade all会在几毫秒内更新同一条记录
parent class
public class Department
{
/** The destination id. */
@Id
@SequenceGenerator(name = ....", sequenceName = ...)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ....)
@Column(name = "DEST_ID", nullable = false, unique = true)
private Long destinationId;
/** The destination name. */
@Column(name = "DEST_NM")
private String destinationName;
/** The Std UTC hour operation . */
@OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@JoinColumn(name = "DEST_ID", nullable = false)
private List<Hours> hrList = new ArrayList<Hours>();
}
child class
public class Hours
{
@Id
@SequenceGenerator(name = ...., sequenceName = ....)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = ....)
@Column(name = "HR_ID")
private Long hoursId;
/** The Destination. */
@ManyToOne(optional = true)
@JoinColumn(name = "DEST_ID", nullable = false, insertable = false, updatable = false)
private Department department;
}
in service class calling -
departmentDao.saveOrupdate(department);
in DAO layer
public void saveOrUpdate(Department departmentToStore) {
em.persist(departmentToStore);
}
我还有其他相关的表格,但它们运行良好。 我只有一对夫妻的关系才有这个问题
注: 表是单向的。 我正在使用persist方法插入记录
请找到完整的代码-
@Entity
@Table(name = "DEPARTMENT")
@XmlRootElement(name = "Department")
public class Department {
/** The destination id. */
@Id
@SequenceGenerator(name = "deptSeq", sequenceName = "SEQ1")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "deptSeq")
@Column(name = "DEST_ID", nullable = false, unique = true)
private Long destinationId;
/** The destination name. */
@Column(name = "DEST_NM")
private String destinationName;
/** The hour operation . */
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "department")
private List<Hours> hoursList = new ArrayList<Hours>();
setter & getters ...
}
@Entity
@Table(name = "HOURS")
@XmlRootElement(name = "SpecialHoursOfOperation")
public class SpecialUTCHoursOfOperation {
/** The hour id. */
@Id
@SequenceGenerator(name = "hourSeq", sequenceName = "SEQ2")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "hourSeq")
@Column(name = "HR_ID")
private Long hourId;
/** The Destination. */
@ManyToOne(optional = true)
@JoinColumn(name = "DEST_ID", nullable = false, insertable = false, updatable = false)
private Department department;
/** The hoursdate. */
@Column(name = "SPEC_HR_OPRT_DT")
private Date HoursDate;
setters and getters
}
DepartmentDAOImpl class -
@Override
@Transactional
public Department saveOrUpdate(Department departmentToStore) {
Department department = new Department();
try {
department = persist(departmentToStore);
} catch (PersistenceException pe) {
pe.getMessage();
}
return department;
}
in DeptService.java
public DepartmentVO storeDepartment(DepartmentVO departmentVO){
Department department = new Department();
department = Helper.populateDepartment(departmentVO);
department.setHoursList(Helper.populateHours(departmentVO, department));
department = departmentDAO.saveOrUpdate(department);
return departmentVO;
}
in Helper.java
public static Department populateDepartment(final DepartmentVO departmentVO) {
Department department = new Department();
department.setDestinationName(departmentVO.getDepartmentName());
return department;
}
public static List<Hours> populateHours(final DepartmentVO departmentVO, final Department department) {
List<Hours> hoursList = new ArrayList<Hours>();
List<HoursVO> hoursVOs = departmentVO.getSpecialDayHourVOs();
for (HoursVO hoursVO : hoursVOs) {
Hours hoursObj = new Hours();
hoursObj.setDepartment(department);
hoursObj.setHoursDate(hoursVO.getSpecialDate());
hoursList.add(hoursObj);
}
return hoursList;
}
数据库表- 部门(目的地id(pk)、目的地nm)、小时(人力资源id(pk)、目的地id(fk)、人力资源dt)
然后我有rest层与前端进行通信。 如果我在调试器到达save方法时运行此代码,它会引发异常。 UniqueCOnstraintviolation ORA-01400:无法将空值插入(小时。“目标ID”)
# 1 楼答案
如果您正在使用一些拦截器来记录审计信息,那么这个问题是由于单向映射造成的。通常情况下,你的部门应该使用mappedBy,而Hours应该使用带有joinColumn的部门参考。这将使它具有双向性。然后在保存时,它不会触发额外的更新查询。 你可以在互联网和jpa的单向深坑瀑布上阅读更多关于inverse=true/false的信息。更改为bi di以防止额外的更新查询